﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Runtime.InteropServices;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;
using CustomXML;

namespace NetChatInterface
{
    public partial class MainForm : Form
    {
        //手动增加的IP地址
        string ipAddrByHand = null;
        protected void OnAddFriend(string ipaddr)
        {
            ipAddrByHand = ipaddr;
            Thread theserver = new Thread(new ThreadStart(ThreadFuncAddFri));//为服务器创建一线程
            theserver.Start();//启动线程
        }
        //线程函数,用来添加朋友
        protected void ThreadFuncAddFri()
        {
            client(ipAddrByHand, FriendstreeView);
            //UpFriendsbutton_Click(null, null);
        }

        //增加的MAINFORM的消息响应
        protected override void DefWndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case MessageType.BTN_RECEIVEDATA:
                    //Receive_File(m.LParam);
                    ThreadPool.QueueUserWorkItem(new WaitCallback(Receive_File), m.LParam);
                    break;
                case MessageType.BTN_SENDFILEDATA:
                    //Send_File(m.LParam);
                    ThreadPool.QueueUserWorkItem(new WaitCallback(Send_File), m.LParam);
                    break;
                case MessageType.MSG_ADDFRI:
                    OnAddFriend(Marshal.PtrToStringAnsi(m.LParam));
                    break;
                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }

        public MainForm()
        {
            InitializeComponent();
            
            //********************************************
            //initialize toolboxs location and size
            UpUsersbutton.BackColor = Color.SkyBlue;
            //*********************************************           
            UpFriendsbutton.Width = this.Width - 5;
            UpUsersbutton.Width = this.Width - 5;
            //********************************************
            DownUsersbutton.Width = this.Width - 6;
            DownUsersbutton.Top = this.Height - 77;
            //********************************************
            FriendstreeView.Width = this.Width - 5;
            FriendstreeView.Height = 282 + this.Height - 420;
            UserstreeView.Width = this.Width - 5;
            UserstreeView.Height = 282 + this.Height - 420;
            //********************************************
            //Aboutbutton.Width = this.Width - Setbutton.Width - Helpbutton.Width - 4;
            //Aboutbutton.Top = this.Height - 57;
            //Setbutton.Top = this.Height - 57;
            Helpbutton.Top = this.Height - 49;
            addFriendButton.Top = this.Height - 49;
            //********************************************

            Thread theserver = new Thread(new ThreadStart(server));//为服务器创建一线程

            theserver.IsBackground = true;//将这个线程设为后台线程

            theserver.Start();//启动线程

            Thread ReceiveMsg = new Thread(new ThreadStart(DataTransfer.receive));

            ReceiveMsg.IsBackground = true;

            ReceiveMsg.Start();

        }


        //************************************************
        //Session Form
        SessionForm SessionFormtest;
        SetForm SetFormtest = new SetForm();
        //************************************************

        //************************************************
       
        [DllImport("user32.dll")]
        
        public static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);
        //************************************************

        private void UpFriendsbutton_Click(object sender, EventArgs e)
        {
            //********************************************
            //UpFriendsbutton_Click the toolboxs's state
            UpFriendsbutton.Show();
            UpUsersbutton.Hide();
            //********************************************
            DownUsersbutton.Show();
            FriendstreeView.Show();
            //********************************************
            UserstreeView.Hide();
            FriendstreeView.Show();
            //********************************************
            UpFriendsbutton.BackColor = Color.SkyBlue;
            DownUsersbutton.BackColor = Color.WhiteSmoke;
            //********************************************
            
            //List<string> SavedMac = new List<string>();
            //SavedMac = MacListManagement.ReadStoredMac();

            //int i = 0;

            //string mac = "";

            //int j = 0;

            //try
            //{

            //do
            //{
            //    mac = GetRemoteMac(ListGetIP[i]);

            //    do
            //    {
            //        if (mac == SavedMac[j])
            //        {
            //            showuser(FriendstreeView);
            //            break;
            //        }

            //        j++;
            //    } while (SavedMac[i] != "");

            //    i++;
            //} while (ListGetIP[i] != "");
            //}
            //catch (System.Exception ee)
            //{

            //}

            client("172.30.19.161", FriendstreeView);//172.30.19.161  222.198.137.95 调试所用

        }


        private void UpUsersbutton_Click(object sender, EventArgs e)
        {
            //********************************************
            //UpUsersbutton_Click the toolboxs's state
            UpFriendsbutton.Show();
            UpUsersbutton.Show();
            //********************************************
            DownUsersbutton.Hide();
            //********************************************
            FriendstreeView.Hide();
            UserstreeView.Show();
            //********************************************
            UpFriendsbutton.BackColor = Color.WhiteSmoke;
            UpUsersbutton.BackColor = Color.SkyBlue;
            //********************************************

            Thread threadclient = new Thread(new ThreadStart(multiclient));

            threadclient.Start();

        }

        private void UpUnfriendsbutton_Click(object sender, EventArgs e)
        {
            //********************************************
            //UpUnfriendsbutton_Click the toolboxs's state
            UpFriendsbutton.Show();
            UpUsersbutton.Show();
            //********************************************
            DownUsersbutton.Hide();
            //********************************************    ;
            FriendstreeView.Hide();
            UserstreeView.Hide();
            //********************************************
            UpFriendsbutton.BackColor = Color.WhiteSmoke;
            UpUsersbutton.BackColor = Color.WhiteSmoke;
            //********************************************
        }

        private void DownUsersbutton_Click(object sender, EventArgs e)
        {
            //********************************************
            //DownUsersbutton_Click the toolboxs's state
            UpFriendsbutton.Show();
            UpUsersbutton.Show();
            //********************************************
            DownUsersbutton.Hide();
            //********************************************
            FriendstreeView.Hide();
            UserstreeView.Show();
            //********************************************
            UpFriendsbutton.BackColor = Color.WhiteSmoke;
            UpUsersbutton.BackColor = Color.SkyBlue;
            //********************************************
        }

        private void DownUnfriendsbutton_Click(object sender, EventArgs e)
        {
            //********************************************
            //DownUnfriendsbutton_Click the toolboxs state
            UpFriendsbutton.Show();
            UpUsersbutton.Show();
            //********************************************
            DownUsersbutton.Hide();
            //********************************************
            FriendstreeView.Hide();
            UserstreeView.Hide();
            //********************************************
            UpFriendsbutton.BackColor = Color.WhiteSmoke;
            UpUsersbutton.BackColor = Color.WhiteSmoke;
            //********************************************
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            //********************************************
            
            AnimateWindow(this.Handle, 500, 12);
            //********************************************

            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void Setbutton_Click(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;//允许线程跨控件访问
            //************************************************
            //Set Head and Skin Color
            if (SetFormtest.ShowDialog() == DialogResult.OK)
            {
                this.BackColor = SetForm.FormBackColor;
                MyHeadpictureBox.BackgroundImage = SetForm.MyHeadImage;
            }
            //************************************************
        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
            //*********************************************
            //For Form Size changed toolboxs's size changed
            UpFriendsbutton.Width = this.Width - 5;
            UpUsersbutton.Width = this.Width - 5;
            //********************************************
            DownUsersbutton.Width = this.Width - 6;
            DownUsersbutton.Top = this.Height - 77;
            //********************************************
            FriendstreeView.Width = this.Width - 5;
            FriendstreeView.Height = 282 + this.Height - 420;
            UserstreeView.Width = this.Width - 5;
            UserstreeView.Height = 282 + this.Height - 420;
            //********************************************
            //Aboutbutton.Width = this.Width - Setbutton.Width - Helpbutton.Width - 4;
            //Aboutbutton.Top = this.Height - 57;
           // Setbutton.Top = this.Height - 57;
            Helpbutton.Top = this.Height - 49;
            addFriendButton.Top = this.Height - 49;
            //********************************************
        }

        private void Helpbutton_Click(object sender, EventArgs e)
        {
            //ChatNoteFormtest = new ChatNoteForm();
            //ChatNoteFormtest.Show();//点击“帮助”按钮显示聊天记录对话框，暂停使用
        }

        private void Aboutbutton_Click(object sender, EventArgs e)
        {
            SessionForm sf = new SessionForm(this.Handle, "222.198.137.90");//这个窗口是用来测试用的
            sf.Show();
        }


        public void server()//local computer's server
        {

            //TcpListener listener = new TcpListener(5000);// create the instance of  TcpListener and the port is 8000

            //listener.Start();// start the listener

            //while (true)//  use the infinite loop in order to recce the user's connected
            //{

            //    TcpClient client = listener.AcceptTcpClient();//  link TcpClient when a connected is recced

            //}

            string strHostName = Dns.GetHostName(); //得到本机的主机名

            IPHostEntry ipEntry = Dns.GetHostByName(strHostName); //取得本机IP

            string strAddr = ipEntry.AddressList[0].ToString();

            IPAddress ServerIp = IPAddress.Parse(strAddr);

            IPEndPoint iep=new IPEndPoint(ServerIp,5000); 

           Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

           socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 500);

           socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 500);

           socket.Bind(iep);

            while(true) 

              { 

            try
            {

                socket.Listen(15);

                Socket newSocket = socket.Accept();

            }

            catch (SocketException ex)
            {

            }

              }




        }


        private string firstip = "172.30.19.";// the first part of ip

        private string secondip;//the second part of ip

        private string ip;

        private int i = 0;

        private List<string> ListGetIP = new List<string>();

        public void multiclient()
        {

            while (i<=254)//judge the value of i ,in order to ensure the range of ip
            {
 
            i++;

            secondip = Convert.ToString(i);//transfer int into string  

            ip = firstip + secondip;//get ip

            client(ip,UserstreeView);
           }
        }


        public void client(string IP,TreeView treeview)// local amchine's client ,send message to the machine endlessly,make sure if linked
        {

            ip = IP;

            //ip = "172.30.19.161";

            //TcpClient tcpClient = new TcpClient();//create the instance of TcpClient

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                ip = IP;
                //IPAddress theip = IPAddress.Parse(ip);//transfer ip

                IPAddress theip = IPAddress.Parse(IP);//172.30.19.161

                IPEndPoint ipe = new IPEndPoint(theip, 5000);

                //tcpClient.Connect(ipe);//create the link

                //if (tcpClient.Connected)//judge the status of linking ,then do the homologous operation
                //{
                //    showuser(UserstreeView);//when we get one user ,we need show him 
                //}

            
                //socket.SendTimeout = 100;

                //socket.ReceiveTimeout = 100;



                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 500);

                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 500);
                socket.SendTimeout = 5;
                socket.ReceiveTimeout = 5;

                socket.Connect(ipe);

            
                if (socket.Connected)
                {
                    showuser(treeview);//when we get one user ,we need show him 

                }

                ListGetIP.Add(ip);

            }
            catch (System.Exception e)
            {
                MessageBox.Show(e.ToString());
            }

            //tcpClient.Close();//close the tcp

            socket.Close();

        }



        public void showuser(TreeView treeView)
        {

            int rich_LocY = 0;

            RichTextBox richtextbox = new RichTextBox();//define new richtextbox control

            richtextbox.Location = new Point(0, rich_LocY);//richtextbox control's position

            richtextbox.Width = this.Width - 10;//  richtextbox control's width

            richtextbox.Height = 30;//  richtextbox control's height

            richtextbox.Text = ip;

            treeView.Controls.Add(richtextbox);//show the richtextbox on treeview control

            PictureBox picture = new PictureBox();//define a new picturebox control

            richtextbox.Controls.Add(picture);// show the picture on the richtextbox

            //System.Drawing.Image image = System.Drawing.Image.FromFile(@"pig.gif");//set the picture's path

            System.Drawing.Image image = System.Drawing.Image.FromFile(@"E:\pig.jpg");//set the picture's path

            picture.Image = image;//show the picture on the picture control

            richtextbox.MouseEnter += new System.EventHandler(this.rich_MouseEnter);//in order to set affair of the new richtextbox,now we set three affairs for the new richtextbox 

            richtextbox.MouseLeave += new System.EventHandler(this.rich_MouseLeave);

            richtextbox.Click += new System.EventHandler(this.rich_Click);//click affair of the new richtextbox control

            rich_LocY += 40;//set the next new richtextbox control's y_coodinate

        }


        private void rich_MouseEnter(object sender, System.EventArgs e)//richtextbox contol's click affair
        {
            RichTextBox currentrichtextbox = (RichTextBox)sender;//get the current richtextbox control 

            currentrichtextbox.BackColor = Color.Blue;   //set the background color of the richtextbox control

            ContextMenu mycontextMenu = new ContextMenu();//append the new menu of the right click

            currentrichtextbox.ContextMenu = mycontextMenu;//

            MenuItem menuItem_Message = new MenuItem();//append new option of the menu
            MenuItem menuItem_Information = new MenuItem();
            MenuItem menuItem_Note = new MenuItem();
            MenuItem menuItem_Setting = new MenuItem();
            MenuItem menuItem_Friend = new MenuItem();

            menuItem_Message.Text = "Send current message";// the text of each option
            menuItem_Information.Text = "look over the information";
            menuItem_Note.Text = "chatting note";
            menuItem_Setting.Text = "setting";
            menuItem_Friend.Text = "accede to  my friends";


            mycontextMenu.MenuItems.Add(menuItem_Message);//accede each option into the menu 
            mycontextMenu.MenuItems.Add(menuItem_Information);
            mycontextMenu.MenuItems.Add(menuItem_Note);
            mycontextMenu.MenuItems.Add(menuItem_Setting);
            mycontextMenu.MenuItems.Add(menuItem_Friend);

            menuItem_Message.Click += new System.EventHandler(this.Msg_Click);// append the affair of clicking every option
            menuItem_Information.Click += new System.EventHandler(this.Inf_Click);
            menuItem_Note.Click += new System.EventHandler(this.Not_Click);
            menuItem_Setting.Click += new System.EventHandler(this.Set_Click);
            menuItem_Friend.Click += new System.EventHandler(this.Fri_Click);

        }


        private void rich_MouseLeave(object sender, System.EventArgs e)//richtextbox control's affair,change the background color to show which is pitched on
        {
            RichTextBox currentrichtextbox = (RichTextBox)sender;

            currentrichtextbox.BackColor = Control.DefaultBackColor;//change the background color
        }

        public struct IpHandle
        {
            public string IP;

            public IntPtr Handle;
        }

        public static List<IpHandle> identity = new List<IpHandle>();

        public static List<SessionForm> listsessionform = new List<SessionForm>();

        private void rich_Click(object sender, System.EventArgs e)//richtextbox control's affair of left clicking
        {

            RichTextBox currentrichtextbox = (RichTextBox)sender;

            
            SessionForm session = new SessionForm(this.Handle, ip);

            foreach (Form form in this.OwnedForms)
            {
                SessionForm anyform = (SessionForm)form;

                if (session.DestinationIP == anyform.DestinationIP)
                {
                    anyform.Activate();
                    session.Dispose();
                    return;
                }
            }
            this.AddOwnedForm(session);
            session.Show();

            listsessionform.Add(session);

            IpHandle iphandle = new IpHandle();

            iphandle.IP = currentrichtextbox.Text;

            iphandle.Handle = session.Handle;

            identity.Add(iphandle);
        }


        private void Msg_Click(object sender, System.EventArgs e)// the affair of sending message int the menu of right clicking
        {

        }

        private void Inf_Click(object sender, System.EventArgs e)//the affair of looking over information  int the menu of right clicking
        {


        }

        private void Not_Click(object sender, System.EventArgs e)//the affair of chatting note int the menu of right clicking
        {

        }

        private void Set_Click(object sender, System.EventArgs e)//the affair of setting int the menu of right clicking
        {

            SetFormtest.Show();
        }
        private List<string> Friend_Mac = new List<string>();

        private void Fri_Click(object sender, System.EventArgs e)//the affair of append to my friends int the menu of right clicking
        {
            RichTextBox currentrichtextbox = (RichTextBox)sender;

           string  TheMac = GetRemoteMac(currentrichtextbox.Text);

           Friend_Mac.Add(TheMac);

          MacListManagement.WriteMacToStore(Friend_Mac);
            
        }

        public void Send_File(object parameter)
        {

            this.Send_File((IntPtr)parameter);

        }

        private IPEndPoint point;

        private void Send_File(IntPtr hHandle)
        {
            


            int i = 0;

            do
            {
                if (listsessionform[i].Handle == hHandle)
                {
                    try
                    {

                        //IPAddress hostAddress = new IPAddress(Encoding.ASCII.GetBytes(listsessionform[i].DestinationIP));
                        //IPEndPoint point = new IPEndPoint(hostAddress, 2000);

                        point = new IPEndPoint(IPAddress.Parse(listsessionform[i].DestinationIP), 2000);

                        byte[] _sendBuf = new byte[1024];

                        TcpClient _tc = new TcpClient();

                        _tc.Connect(point);



                        NetworkStream _ns = _tc.GetStream();

                        string path = listsessionform[i].FilePath ;

                        FileStream fs = new FileStream(path, FileMode.Open);

                        int sendCount = 0;

                        while (sendCount < fs.Length && _ns.CanWrite)
                        {
                            int count = fs.Read(_sendBuf, 0, _sendBuf.Length);

                            _ns.Write(_sendBuf, 0, count);

                            sendCount += count;
                        }
                        fs.Close();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("连接出错");
                    }
                    break;

                }
                i++;
            } while (listsessionform[i] != null);
        }

        public void Receive_File(object parameter)
        {

            this.Receive_File((IntPtr)parameter);

        }

        private void Receive_File(IntPtr hHandle)
        {
            int i = 0;
            byte[] _receiveBuf = new byte[1024];
            IPHostEntry ipHostInfo = Dns.GetHostByName(System.Net.Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            TcpListener _ls = new TcpListener(ipAddress, 2000);
            _ls.Start();
            do
            {
                if (listsessionform[i].Handle == hHandle)
                {



                    while (true)
                    {

                        TcpClient tc = _ls.AcceptTcpClient();

                        NetworkStream ns = tc.GetStream();

                        bool isRead = true;

                        try
                        {
                            FileStream fs = new FileStream(listsessionform[i].FileStoreDirectory+listsessionform[i].filename, FileMode.OpenOrCreate);

                            while (isRead)
                            {
                                int count = ns.Read(_receiveBuf, 0, _receiveBuf.Length);
                                if (count < _receiveBuf.Length)
                                    isRead = false;
                                fs.Write(_receiveBuf, 0, count);
                            }

                            fs.Close();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message + "frmReceive::Receive");
                        }

                    }
                    break;
                }
                i++;

            } while (listsessionform[i] != null);

            _ls.Stop();
        }

        //获取远程主机MAC
        [DllImport("Iphlpapi.dll")]

        private static extern int SendARP(Int32 dest, Int32 host, ref IntPtr mac, ref IntPtr length);

        [DllImport("Ws2_32.dll")]

        private static extern Int32 inet_addr(string ip);

        private string GetRemoteMac(string remoteip)
        {

            string strHostName = Dns.GetHostName(); //得到本机的主机名

            IPHostEntry ipEntry = Dns.GetHostByName(strHostName); //取得本机IP

            string strAddr = ipEntry.AddressList[0].ToString();

            Int32 ldest = inet_addr(remoteip);//目的地的ip

            Int32 lhost = inet_addr(strAddr);//本地的ip

            Byte[] macinfo = new Byte[6];

            Int32 length = 6;

            IntPtr mac = new IntPtr(macinfo[0]);

            IntPtr len = new IntPtr(6);

            try
            {

                int ii = SendARP(ldest, lhost, ref mac, ref len);

            }
            catch (Exception err)
            {

            }
            return Convert.ToString(mac);
        }

        private void addFriendButton_Click(object sender, EventArgs e)
        {
            QuickAddFriend qaf = new QuickAddFriend(this.Handle);
            qaf.Show();
        }

        private void IPlabel_Click(object sender, EventArgs e)
        {

        }
    }
}
